package org.hiberlyzer.impl;

import java.util.Collection;
import java.util.Map;
import java.util.TreeSet;

import org.hiberlyzer.Metadata;
import org.hiberlyzer.Property;
import org.hibernate.EntityMode;
import org.hibernate.metadata.ClassMetadata;

public class MetadataImpl implements Metadata
{
	private EntityMode hibernateEntityMode;
	private ClassMetadata hibernateMetadata;
	
	MetadataImpl(ClassMetadata classMetadata, EntityMode entityMode)
	{
		this.hibernateMetadata = classMetadata;
		this.hibernateEntityMode = entityMode;
	}

	public Property getIdentifier()
	{
		return new Property(){
			public String getName()
			{
				return MetadataImpl.this.hibernateMetadata.getIdentifierPropertyName();
			}

			public String getType()
			{
				return MetadataImpl.this.hibernateMetadata.getIdentifierType().getName();
			}

			public Object getValue(Object object)
			{
				return MetadataImpl.this.hibernateMetadata.getIdentifier(object, MetadataImpl.this.hibernateEntityMode);
			}
		};
	}

	public Collection<Property> getProperties()
	{
		Collection<Property> properties = new TreeSet<Property>();
		for(String propertyName : this.hibernateMetadata.getPropertyNames())
		{
			properties.add(new PropertyImpl(propertyName));
		}
		return properties;
	}

	public Map<Class, Metadata> getSubclassMetadata()
	{
		System.err.println("*getSubclassMetadata() - not implemented*");
		return null;
	}

	class PropertyImpl implements Property, Comparable<Property>
	{
		private String _name;
		
		PropertyImpl(String name)
		{
			this._name = name;
		}
		
		public String getName()
		{
			return _name;
		}

		public String getType()
		{
			return MetadataImpl.this.hibernateMetadata.getPropertyType(getName()).getName();
		}

		public Object getValue(Object object)
		{
			return MetadataImpl.this.hibernateMetadata.getPropertyValue(
					object, getName(), MetadataImpl.this.hibernateEntityMode);
		}

		public int compareTo(Property other)
		{
			return getName().compareToIgnoreCase(other.getName());
		}
	}
}
